from contextlib import asynccontextmanager
import time
import uuid

from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import logging
from fastapi.exceptions import RequestValidationError
from fastapi.security import HTTPBearer
from fastapi.openapi.utils import get_openapi
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY

from app.settings import settings
from app.routers import auth, users

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)


@asynccontextmanager
async def lifespan(app: FastAPI):
    if not settings.jwt_secret or settings.jwt_secret == "changeme":
        logging.getLogger("app.error").warning("JWT_SECRET is not set or insecure; set it in environment for secure operation")
    yield


app = FastAPI(
    title=settings.app_name,
    description="AI招聘系统API - 提供用户认证、用户管理等功能",
    version="1.0.0",
    lifespan=lifespan,
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json"
)

# CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 可根据需要收紧为具体前端域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Request ID & latency logging middleware
@app.middleware("http")
async def add_request_id_and_logging(request: Request, call_next):
    request_id = str(uuid.uuid4())
    request.state.request_id = request_id
    start = time.perf_counter()
    try:
        response = await call_next(request)
    finally:
        duration_ms = (time.perf_counter() - start) * 1000
        # 使用自定义的日志记录器而不是 uvicorn.access
        logging.getLogger("app.access").info(
            f"Request completed - ID: {request_id}, Method: {request.method}, Path: {request.url.path}, Status: {getattr(response, 'status_code', 0)}, Duration: {round(duration_ms, 2)}ms"
        )
    response.headers["X-Request-ID"] = request_id
    return response

# Instantiate to ensure OpenAPI components include bearer scheme
security_scheme = HTTPBearer()


@app.get("/.well-known/appspecific/com.chrome.devtools.json")
async def chrome_devtools_config() -> dict:
    """Chrome DevTools配置文件，用于消除Chrome DevTools的404错误"""
    return {"version": "1.0", "description": "AI招聘系统API"}


@app.get(
    "/api/health",
    tags=["系统监控"],
    summary="健康检查",
    description="检查API服务是否正常运行",
    response_description="返回服务状态信息"
)
async def health() -> dict:
    """
    健康检查端点
    
    用于监控系统检查API服务是否正常运行。
    返回简单的状态信息。
    """
    return {"status": "ok", "service": "ai-recruitment-api"}


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=HTTP_422_UNPROCESSABLE_ENTITY,
        content={"error": "validation_error", "message": "Validation failed", "details": exc.errors()},
    )


@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    if isinstance(exc.detail, dict):
        payload = exc.detail
    else:
        payload = {"error": "http_error", "message": str(exc.detail)}
    return JSONResponse(status_code=exc.status_code, content=payload, headers=getattr(exc, "headers", None))


@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    logging.getLogger("app.error").exception("unhandled_exception")
    return JSONResponse(status_code=500, content={"error": "internal_error", "message": "Internal server error"})


# Routers under /api
app.include_router(auth.router, prefix="/api")
app.include_router(users.router, prefix="/api")


def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        title=app.title,
        version="1.0.0",
        description="""
        ## AI招聘系统API
        
        这是一个基于FastAPI构建的AI招聘系统后端API，提供以下功能：
        
        ### 🔐 认证功能
        - 用户登录认证
        - JWT令牌管理
        
        ### 👥 用户管理
        - 获取当前用户信息
        - 用户权限管理
        
        ### 🔒 安全特性
        - JWT Bearer认证
        - 基于角色的访问控制(RBAC)
        
        ### 📊 系统监控
        - 健康检查端点
        - 请求日志记录
        
        ## 使用说明
        
        1. 首先通过 `/api/auth/login` 进行登录获取访问令牌
        2. 在后续请求中使用 `Authorization: Bearer <token>` 头部
        3. 不同角色(hr, interviewer, boss)具有不同的访问权限
        """,
        routes=app.routes,
    )
    components = openapi_schema.setdefault("components", {})
    security_schemes = components.setdefault("securitySchemes", {})
    security_schemes["bearerAuth"] = {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT Bearer令牌认证，在登录后获取访问令牌"
    }
    
    # 添加全局安全要求
    openapi_schema["security"] = [{"bearerAuth": []}]
    
    # 添加联系信息
    openapi_schema["info"]["contact"] = {
        "name": "AI招聘系统开发团队",
        "email": "dev@ai-recruitment.com"
    }
    
    # 添加许可证信息
    openapi_schema["info"]["license"] = {
        "name": "MIT",
        "url": "https://opensource.org/licenses/MIT"
    }
    
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi 